package com.company.project.controller;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.company.project.common.aop.annotation.LogAnnotation;
import com.company.project.common.exception.BusinessException;
import com.company.project.common.exception.code.BaseResponseCode;
import com.company.project.common.utils.Constant;
import com.company.project.common.utils.DataResult;
import com.company.project.common.utils.EnumAreaType;
import com.company.project.common.utils.EnumCommonUserType;
import com.company.project.common.utils.EnumGroupType;
import com.company.project.common.utils.FileTypeUtil;
import com.company.project.entity.CommonUserEntity;
import com.company.project.entity.MatchProjectEntity;
import com.company.project.entity.MatchTeamEntity;
import com.company.project.entity.SysFilesEntity;
import com.company.project.entity.SysUser;
import com.company.project.entity.TeamUserEntity;
import com.company.project.service.CommonUserService;
import com.company.project.service.HttpSessionService;
import com.company.project.service.MatchProjectService;
import com.company.project.service.MatchTeamService;
import com.company.project.service.SysFilesService;
import com.company.project.service.TeamUserService;
import com.company.project.service.UserService;
import com.company.project.vo.req.CommonUserDTO;
import com.company.project.vo.req.EnrollProjectDTO;
import com.company.project.vo.req.FrontProjectDTO;
import com.company.project.vo.req.UpdateEnrollProjectDTO;
import com.company.project.vo.req.UpdatePersonalInfo;
import com.company.project.vo.req.UpdatePwdDTO;
import com.company.project.vo.resp.PersonalInfo;
import com.company.project.vo.resp.ProjectDetailDTO;
import com.company.project.vo.resp.TeamInfo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 
 * Title: EnrollController.java  
 * Description:     
 * @author LS  
 * @date 2021-2-3 9:51:10  
 * @version 1.0
 */
@RequestMapping("/enroll")
@RestController
@Api(tags = "比赛模块-项目报名")
public class EnrollProjectController extends BaseController{
	
	@Resource
    private UserService userService;
	
	@Resource
	private CommonUserService commonUserService;
	
	@Resource
	private MatchTeamService matchTeamService;
	
	@Resource
	private MatchProjectService matchProjectService;
	
	@Resource
	private TeamUserService teamUserService;
	
	@Resource
    private SysFilesService sysFilesService;
	
	@Resource
    private HttpSessionService httpSessionService;
	
	@Transactional(rollbackFor = Exception.class)
	@PostMapping("/add")
    @ApiOperation(value = "项目报名接口")
    @LogAnnotation(title = "比赛模块", action = "项目报名")
    @RequiresPermissions("enroll:project:add")
	public DataResult enroll(@RequestBody @Valid EnrollProjectDTO dto) {
		//比赛报名是否开启
		if(getMatchStatus()) {
			TeamUserEntity teamUser = getCurrentTeamUser();		
			if(teamUser.getIsCaptain().equals(Constant.IS_TRUE)) {
				//团队已有项目
				List<MatchProjectEntity> pros = matchProjectService.list(Wrappers.<MatchProjectEntity>lambdaQuery().eq(MatchProjectEntity::getTeamId, teamUser.getTeamId()));
				if (pros != null && pros.size() >= 1) {
					throw new BusinessException(BaseResponseCode.TEAM_EXIST_PROJECT);
				}
				MatchTeamEntity team = matchTeamService.getById(teamUser.getTeamId());
				// 添加项目
				MatchProjectEntity project = new MatchProjectEntity();
				BeanUtils.copyProperties(dto, project);
				project.setTeamId(teamUser.getTeamId());
				if (!StringUtils.isEmpty(project.getFile())) {				
					SysFilesEntity file = sysFilesService
							.getOne(Wrappers.<SysFilesEntity>lambdaQuery().eq(SysFilesEntity::getUrl, project.getFile()));
					if(file!=null) {
						String oldFileName = file.getUrl().substring(file.getUrl().lastIndexOf("/") + 1, file.getUrl().length());
						String path = file.getUrl().substring(0,file.getUrl().lastIndexOf("/")+1);					
						String newFileName = EnumAreaType.getName(team.getArea())+"-"+EnumGroupType.getName(project.getGroupName())+"-"+oldFileName;
						sysFilesService.renameFile(file.getId(), newFileName);
						project.setFileName(newFileName);				
						project.setFile(path+newFileName);
					}							
				}
				matchProjectService.addMatchProject(project);
				// 添加创始人和联系人
				if (dto.getContactsUsers() == null || dto.getContactsUsers().size() <= 0) {
					throw new BusinessException("请添加联系人!");
				}
				if (dto.getFounderUsers() == null || dto.getFounderUsers().size() <= 0) {
					throw new BusinessException("请添加创始人!");
				}
				// 存储
				for (CommonUserDTO cu : dto.getContactsUsers()) {
					CommonUserEntity entity = new CommonUserEntity();
					BeanUtils.copyProperties(cu, entity);
					entity.setProjectId(project.getProjectId());
					entity.setType(Constant.Contacts);
					commonUserService.addCommonUser(entity);
				}
				for (CommonUserDTO cu : dto.getFounderUsers()) {
					CommonUserEntity entity = new CommonUserEntity();
					BeanUtils.copyProperties(cu, entity);
					entity.setProjectId(project.getProjectId());
					entity.setType(Constant.Founder);
					commonUserService.addCommonUser(entity);
				}
			}else {
				throw new BusinessException(BaseResponseCode.FORBIDDEN);
			}	
			return DataResult.success();
		}else {
			throw new BusinessException(BaseResponseCode.MATCH_STATUS_STOP);
		}
		
	}
	
	//更改报名信息
	@Transactional(rollbackFor = Exception.class)
	@PostMapping("/update")
    @ApiOperation(value = "项目修改接口")
    @LogAnnotation(title = "比赛模块", action = "项目修改")
    @RequiresPermissions("enroll:project:update")
	public DataResult update(@RequestBody @Valid UpdateEnrollProjectDTO dto) {
		//比赛报名是否开启
		if(getMatchStatus()) {
			if(isCaptain()) {
				//更改项目	
				MatchProjectEntity project = matchProjectService
						.getOne(Wrappers.<MatchProjectEntity>lambdaQuery().eq(MatchProjectEntity::getProjectId, dto.getProjectId()));
				if (null == project) {
					throw new BusinessException(BaseResponseCode.DATA_ERROR + "，项目不存在！");
				}
				MatchTeamEntity team = matchTeamService.getById(project.getTeamId());
				String oldUrl = project.getFile();		
				BeanUtils.copyProperties(dto, project);
				if (!StringUtils.isEmpty(oldUrl) && !oldUrl.equals(dto.getFile())) {				
					SysFilesEntity file = sysFilesService
							.getOne(Wrappers.<SysFilesEntity>lambdaQuery().eq(SysFilesEntity::getUrl, project.getFile()));
					if(file!=null) {
						String oldFileName = file.getUrl().substring(file.getUrl().lastIndexOf("/") + 1, file.getUrl().length());
						String path = file.getUrl().substring(0,file.getUrl().lastIndexOf("/")+1);					
						String newFileName = EnumAreaType.getName(team.getArea())+"-"+EnumGroupType.getName(project.getGroupName())+"-"+oldFileName;
						sysFilesService.renameFile(file.getId(), newFileName);
						project.setFileName(newFileName);				
						project.setFile(path+newFileName);
					}							
				}
				matchProjectService.updateById(project);						
				
				//更改联系人创始人（先全部删除，再添加）
				if(dto.getContactsUsers()==null || dto.getContactsUsers().size()<=0) {
					throw new BusinessException("请添加联系人!");
				}
				if(dto.getFounderUsers()==null || dto.getFounderUsers().size()<=0) {
					throw new BusinessException("请添加创始人!");
				}		
				commonUserService.remove(Wrappers.<CommonUserEntity>lambdaQuery().eq(CommonUserEntity::getProjectId, project.getProjectId()));		
				//存储
				for(CommonUserDTO cu:dto.getContactsUsers()) {
					CommonUserEntity entity = new CommonUserEntity();
					BeanUtils.copyProperties(cu, entity);
					entity.setProjectId(project.getProjectId());
					entity.setType(Constant.Contacts);
					commonUserService.addCommonUser(entity);
				}
				for(CommonUserDTO cu:dto.getFounderUsers()) {
					CommonUserEntity entity = new CommonUserEntity();
					BeanUtils.copyProperties(cu, entity);
					entity.setProjectId(project.getProjectId());
					entity.setType(Constant.Founder);
					commonUserService.addCommonUser(entity);
				}
				//删除旧文件
				if(!StringUtils.isEmpty(oldUrl) && !oldUrl.equals(dto.getFile())) {
					SysFilesEntity file = sysFilesService
							.getOne(Wrappers.<SysFilesEntity>lambdaQuery().eq(SysFilesEntity::getUrl, oldUrl));
					if(file != null) {
						List<String> ids = new ArrayList<>();
						ids.add(file.getId());
						sysFilesService.removeByIdsAndFiles(ids);
					}		
				}
			}else {
				throw new BusinessException(BaseResponseCode.FORBIDDEN);
			}								
			return DataResult.success();
		}else {
			throw new BusinessException(BaseResponseCode.MATCH_STATUS_STOP);
		}
			
	}
	
	//查看报名信息
	@GetMapping("/view/{projectId}")
	@ApiOperation(value = "项目查看接口")
	@LogAnnotation(title = "比赛模块", action = "项目查看")
	@RequiresPermissions("enroll:project:view")
	public DataResult view(@PathVariable("projectId") String projectId) {		
		// 项目信息
		MatchProjectEntity project = matchProjectService
				.getOne(Wrappers.<MatchProjectEntity>lambdaQuery().eq(MatchProjectEntity::getProjectId, projectId));
		if (null == project) {
			throw new BusinessException(BaseResponseCode.DATA_ERROR + "，项目不存在！");
		}
		if(StringUtils.isEmpty(project.getFile())) {
			String file =project.getFile();
			String fileName = file.substring(file.lastIndexOf("/")+1, file.length());
			project.setFileName(fileName);
		}
		project.setGroupCN(EnumGroupType.getName(project.getGroupName()));	
		// 队伍信息
		MatchTeamEntity team = matchTeamService
				.getOne(Wrappers.<MatchTeamEntity>lambdaQuery().eq(MatchTeamEntity::getTeamId, project.getTeamId()));
		if (null == team) {
			throw new BusinessException(BaseResponseCode.DATA_ERROR + "，队伍不存在！");
		}		
		// 获取所有队员
		List<TeamUserEntity> teamusers = teamUserService
				.list(Wrappers.<TeamUserEntity>lambdaQuery().eq(TeamUserEntity::getTeamId, team.getTeamId()));

		// 获取所有公共用户contactsUsers founderUsers
		List<CommonUserEntity> contactsUsers = commonUserService
				.list(Wrappers.<CommonUserEntity>lambdaQuery().eq(CommonUserEntity::getProjectId, projectId).eq(CommonUserEntity::getType, "2"));
		
		List<CommonUserEntity> founderUsers = commonUserService
				.list(Wrappers.<CommonUserEntity>lambdaQuery().eq(CommonUserEntity::getProjectId, projectId).eq(CommonUserEntity::getType, "1"));
				
		ProjectDetailDTO dto = new ProjectDetailDTO();
		dto.setProject(project);
		dto.setTeam(team);
		dto.setTeamusers(teamusers);
		
		dto.setContactsUsers(contactsUsers);
		dto.setFounderUsers(founderUsers);
		return DataResult.success(dto);
	}
	
	//删除项目
	@Transactional(rollbackFor = Exception.class)
	@GetMapping("/delete/{projectId}")
	@ApiOperation(value = "项目删除接口")
	@LogAnnotation(title = "比赛模块", action = "项目删除")
	@RequiresPermissions("enroll:project:delete")
	public DataResult delete(@PathVariable("projectId") String projectId) {
		//比赛报名是否开启
		if(getMatchStatus()) {
			if (isCaptain()) {
				// 项目信息
				MatchProjectEntity project = matchProjectService
						.getOne(Wrappers.<MatchProjectEntity>lambdaQuery().eq(MatchProjectEntity::getProjectId, projectId));
				if (null == project) {
					throw new BusinessException(BaseResponseCode.DATA_ERROR + "，项目不存在！");
				}
				// 删除创始人联系人
				commonUserService
						.remove(Wrappers.<CommonUserEntity>lambdaQuery().eq(CommonUserEntity::getProjectId, projectId));
				// 删除附件
				String url = project.getFile();
				if (!StringUtils.isEmpty(url)) {
					SysFilesEntity file = sysFilesService
							.getOne(Wrappers.<SysFilesEntity>lambdaQuery().eq(SysFilesEntity::getUrl, url));
					if(file!=null) {
						List<String> ids = new ArrayList<>();
						ids.add(file.getId());
						sysFilesService.removeByIdsAndFiles(ids);
					}			
				}
				// 删除项目
				matchProjectService.removeById(projectId);
				return DataResult.success();
			} else {
				throw new BusinessException(BaseResponseCode.FORBIDDEN);
			}
		}else {
			throw new BusinessException(BaseResponseCode.MATCH_STATUS_STOP);
		}
		
	}

	//查看项目列表
	@GetMapping("/viewlist")
	@ApiOperation(value = "项目列表查看接口")
	@LogAnnotation(title = "比赛模块", action = "项目列表查看")
	@RequiresPermissions("enroll:project:viewlist")
	public DataResult viewlist() {
		List<FrontProjectDTO> dtos = new ArrayList<>();
		// 个人信息
		SysUser currentUser = getCurrentUser();		
		// 获取队伍ID
		TeamUserEntity teamUser = teamUserService.getOne(
				Wrappers.<TeamUserEntity>lambdaQuery().eq(TeamUserEntity::getIdNumber, currentUser.getIdNumber()));
		if (null == teamUser) {
			return DataResult.success(dtos);
		}
		// 获取队伍信息
		MatchTeamEntity team = matchTeamService
				.getOne(Wrappers.<MatchTeamEntity>lambdaQuery().eq(MatchTeamEntity::getTeamId, teamUser.getTeamId()));
		if (null == team) {
			throw new BusinessException(BaseResponseCode.NO_TEAM);
		}
		// 项目信息
		List<MatchProjectEntity> projects = matchProjectService.list(
				Wrappers.<MatchProjectEntity>lambdaQuery().eq(MatchProjectEntity::getTeamId, teamUser.getTeamId()));
		for (MatchProjectEntity mp : projects) {
			FrontProjectDTO fp = new FrontProjectDTO();
			BeanUtils.copyProperties(mp, fp);
			fp.setTeamName(team.getTeamName());
			fp.setGroupCN(EnumGroupType.getName(mp.getGroupName()));

			CommonUserEntity founderuser = commonUserService.getOne(
					Wrappers.<CommonUserEntity>lambdaQuery().eq(CommonUserEntity::getProjectId, mp.getProjectId())
							.eq(CommonUserEntity::getType, EnumCommonUserType.FOUNDER.getIndex()).last("limit 1"));
			if (null == founderuser) {
				throw new BusinessException("项目没有创始人！");
			}
			fp.setFounderName(founderuser.getName());
			fp.setFounderPhone(founderuser.getPhone());

			CommonUserEntity contantsuser = commonUserService.getOne(
					Wrappers.<CommonUserEntity>lambdaQuery().eq(CommonUserEntity::getProjectId, mp.getProjectId())
							.eq(CommonUserEntity::getType, EnumCommonUserType.CONTANTS.getIndex()).last("limit 1"));
			if (null == contantsuser) {
				throw new BusinessException("项目没有联系人！");
			}
			fp.setContansName(contantsuser.getName());
			fp.setContansPhone(contantsuser.getPhone());
			dtos.add(fp);
		}
		return DataResult.success(dtos);
	}	
	
	@ApiOperation(value = "查看个人信息")
    @PostMapping("/personalInfo")  
	@RequiresPermissions("enroll:project:personalInfo")
    public DataResult personalInfo() {
        SysUser user = getCurrentUser();               		    
        PersonalInfo personalInfo = new PersonalInfo();
        BeanUtils.copyProperties(user, personalInfo);
        String isCaptain = null;       
        TeamUserEntity teamUser = teamUserService
				.getOne(Wrappers.<TeamUserEntity>lambdaQuery().eq(TeamUserEntity::getDcicUserId, getCurrentUser().getDcicUserId()));
		if (teamUser == null) {
			isCaptain = Constant.IS_NEW;
		} else {
			isCaptain = teamUser.getIsCaptain();
		}     
        personalInfo.setIsCaptain(isCaptain);
        return DataResult.success(personalInfo);
    }
	
	@ApiOperation(value = "前端修改个人信息")
	@Transactional(rollbackFor = Exception.class)
    @PostMapping("/updatePersonalInfo")
	@RequiresPermissions("enroll:project:updatePersonalInfo")
    public DataResult updatePersonalInfo(@RequestBody @Valid UpdatePersonalInfo dto) {
		//比赛报名是否开启
		if(getMatchStatus()) {
			//更新sys_user表
			SysUser user = getCurrentUser();       
	        BeanUtils.copyProperties(dto, user);      
	        userService.updateById(user);
	        //更新team_user表
	        TeamUserEntity teamUser = teamUserService
					.getOne(Wrappers.<TeamUserEntity>lambdaQuery().eq(TeamUserEntity::getDcicUserId, getCurrentUser().getDcicUserId()));
			if(teamUser != null){
				BeanUtils.copyProperties(dto, teamUser);
				teamUserService.updateById(teamUser);
			}      		
	        return DataResult.success();
		}else {
			throw new BusinessException(BaseResponseCode.MATCH_STATUS_STOP);
		}
		
    }
	
	//更改密码
	@PutMapping("/updatepwd")
	@ApiOperation(value = "修改密码接口")
	@LogAnnotation(title = "用户管理", action = "更新密码")
	@RequiresPermissions("enroll:project:updatepwd")
	public DataResult updatePwd(@RequestBody @Valid UpdatePwdDTO vo) {
		if (StringUtils.isEmpty(vo.getOldPwd()) || StringUtils.isEmpty(vo.getNewPwd())) {
			return DataResult.fail("旧密码与新密码不能为空");
		}
		userService.updatePwd(vo);
		return DataResult.success();
	}
	
	@GetMapping("/logout")
    @ApiOperation(value = "退出接口")
    @LogAnnotation(title = "用户管理", action = "退出")
	@RequiresPermissions("enroll:project:logout")
    public DataResult logout() {
        httpSessionService.abortUserByToken();
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return DataResult.success();
    }
	
	@ApiOperation(value = "团队信息")
    @PostMapping("/teamInfo")
	@RequiresPermissions("enroll:project:teamInfo")
    public DataResult teamInfo() {
		String userId = httpSessionService.getCurrentUserId();
        SysUser user = userService.getById(userId);
        TeamInfo teamInfo = new TeamInfo();
        TeamUserEntity teamuser = teamUserService
				.getOne(Wrappers.<TeamUserEntity>lambdaQuery().eq(TeamUserEntity::getIdNumber, user.getIdNumber()));
		if (teamuser != null) {
			MatchTeamEntity team = matchTeamService.getOne(
					Wrappers.<MatchTeamEntity>lambdaQuery().eq(MatchTeamEntity::getTeamId, teamuser.getTeamId()));
			BeanUtils.copyProperties(team, teamInfo);
			List<TeamUserEntity> teamusers = teamUserService
					.list(Wrappers.<TeamUserEntity>lambdaQuery().eq(TeamUserEntity::getTeamId, team.getTeamId()));
			teamInfo.setListUser(teamusers);
		}else {
			throw new BusinessException(BaseResponseCode.NO_TEAM);
		}
        return DataResult.success(teamInfo);
    }
	
	@ApiOperation(value = "添加附件")
    @PostMapping("/upload")  
	@RequiresPermissions("enroll:project:upload")
    public DataResult add(@RequestParam(value = "file") MultipartFile file) {
		//比赛报名是否开启
		if(getMatchStatus()) {
			//判断文件是否空
	        if (file == null || file.getOriginalFilename() == null || "".equalsIgnoreCase(file.getOriginalFilename().trim())) {
	            return DataResult.fail("文件为空");
	        }
	        String fileName = file.getOriginalFilename();
	        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
	        if(!FileTypeUtil.verifyCompressFileType(fileType)) {
	        	throw new BusinessException(BaseResponseCode.FILE_TYPE_ERROR);
	        }
	        return sysFilesService.saveFile(file,Constant.ATTACHMENT);
		}else {
			throw new BusinessException(BaseResponseCode.MATCH_STATUS_STOP);
		}
		
    }
	
	@ApiOperation(value = "获取项目策划书url")
    @PostMapping("/getProjectPlan")
	@RequiresPermissions("enroll:project:getProjectPlan")   
    public DataResult getProjectPlan() {
		SysFilesEntity sysFilesEntity = sysFilesService.getOne(Wrappers.<SysFilesEntity>lambdaQuery().eq(SysFilesEntity::getType, Constant.PROJECTPLAN));	
        if(sysFilesEntity != null) {
        	return DataResult.success(sysFilesEntity.getUrl());
        }
        return DataResult.success();
    }
	
	@ApiOperation(value = "前端查询模板文件数据")
	@PostMapping("/listAttachment")
	@RequiresPermissions("enroll:project:listAttachment")
	public DataResult findListAttachmentByPage(/*@RequestBody @Valid PageParam param*/) {
		//Page page = new Page(param.getPageIndex(), param.getPageSize());
		LambdaQueryWrapper<SysFilesEntity> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(SysFilesEntity::getType, Constant.PROJECTPLAN);
		queryWrapper.or();
		queryWrapper.eq(SysFilesEntity::getType, Constant.TEMPLATEFILE);
		queryWrapper.orderByAsc(SysFilesEntity::getType);

		List<SysFilesEntity> list = sysFilesService.list(queryWrapper);
		//IPage<SysFilesEntity> list = sysFilesService.page(page,queryWrapper);
		return DataResult.success(list);
	}
}
